home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / lib / iceweasel / components / nsBrowserGlue.js < prev    next >
Encoding:
Text File  |  2013-01-09  |  58.5 KB  |  1,428 lines

  1. //@line 44 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  2.  
  3. const Ci = Components.interfaces;
  4. const Cc = Components.classes;
  5. const Cr = Components.results;
  6. const Cu = Components.utils;
  7.  
  8. const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  9.  
  10. Cu.import("resource://gre/modules/XPCOMUtils.jsm");
  11. Cu.import("resource://gre/modules/Services.jsm");
  12. Cu.import("resource://gre/modules/AddonManager.jsm");
  13.  
  14. XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
  15.   Cu.import("resource://gre/modules/NetUtil.jsm");
  16.   return NetUtil;
  17. });
  18.  
  19. XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() {
  20.   Cu.import("resource://gre/modules/PlacesUtils.jsm");
  21.   return PlacesUtils;
  22. });
  23.  
  24. const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
  25. const PREF_PLUGINS_UPDATEURL  = "plugins.update.url";
  26.  
  27. // We try to backup bookmarks at idle times, to avoid doing that at shutdown.
  28. // Number of idle seconds before trying to backup bookmarks.  15 minutes.
  29. const BOOKMARKS_BACKUP_IDLE_TIME = 15 * 60;
  30. // Minimum interval in milliseconds between backups.
  31. const BOOKMARKS_BACKUP_INTERVAL = 86400 * 1000;
  32. // Maximum number of backups to create.  Old ones will be purged.
  33. const BOOKMARKS_BACKUP_MAX_BACKUPS = 10;
  34.  
  35. // Factory object
  36. const BrowserGlueServiceFactory = {
  37.   _instance: null,
  38.   createInstance: function BGSF_createInstance(outer, iid) {
  39.     if (outer != null)
  40.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  41.     return this._instance == null ?
  42.       this._instance = new BrowserGlue() : this._instance;
  43.   }
  44. };
  45.  
  46. // Constructor
  47.  
  48. function BrowserGlue() {
  49.   XPCOMUtils.defineLazyServiceGetter(this, "_idleService",
  50.                                      "@mozilla.org/widget/idleservice;1",
  51.                                      "nsIIdleService");
  52.  
  53.   XPCOMUtils.defineLazyGetter(this, "_distributionCustomizer", function() {
  54.                                 Cu.import("resource:///modules/distribution.js");
  55.                                 return new DistributionCustomizer();
  56.                               });
  57.  
  58.   XPCOMUtils.defineLazyGetter(this, "_sanitizer",
  59.     function() {
  60.       let sanitizerScope = {};
  61.       Services.scriptloader.loadSubScript("chrome://browser/content/sanitize.js", sanitizerScope);
  62.       return sanitizerScope.Sanitizer;
  63.     });
  64.  
  65.   this._init();
  66. }
  67.  
  68. //@line 115 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  69.  
  70. BrowserGlue.prototype = {
  71.   _saveSession: false,
  72.   _isIdleObserver: false,
  73.   _isPlacesInitObserver: false,
  74.   _isPlacesLockedObserver: false,
  75.   _isPlacesShutdownObserver: false,
  76.   _isPlacesDatabaseLocked: false,
  77.  
  78.   _setPrefToSaveSession: function BG__setPrefToSaveSession(aForce) {
  79.     if (!this._saveSession && !aForce)
  80.       return;
  81.  
  82.     Services.prefs.setBoolPref("browser.sessionstore.resume_session_once", true);
  83.  
  84.     // This method can be called via [NSApplication terminate:] on Mac, which
  85.     // ends up causing prefs not to be flushed to disk, so we need to do that
  86.     // explicitly here. See bug 497652.
  87.     Services.prefs.savePrefFile(null);
  88.   },
  89.  
  90. //@line 137 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  91.   _setSyncAutoconnectDelay: function BG__setSyncAutoconnectDelay() {
  92.     // Assume that a non-zero value for services.sync.autoconnectDelay should override
  93.     if (Services.prefs.prefHasUserValue("services.sync.autoconnectDelay")) {
  94.       let prefDelay = Services.prefs.getIntPref("services.sync.autoconnectDelay");
  95.  
  96.       if (prefDelay > 0)
  97.         return;
  98.     }
  99.  
  100.     // delays are in seconds
  101.     const MAX_DELAY = 300;
  102.     let delay = 3;
  103.     let browserEnum = Services.wm.getEnumerator("navigator:browser");
  104.     while (browserEnum.hasMoreElements()) {
  105.       delay += browserEnum.getNext().gBrowser.tabs.length;
  106.     }
  107.     delay = delay <= MAX_DELAY ? delay : MAX_DELAY;
  108.  
  109.     Cu.import("resource://services-sync/main.js");
  110.     Weave.SyncScheduler.delayedAutoConnect(delay);
  111.   },
  112. //@line 159 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  113.  
  114.   // nsIObserver implementation 
  115.   observe: function BG_observe(subject, topic, data) {
  116.     switch (topic) {
  117.       case "xpcom-shutdown":
  118.         this._dispose();
  119.         break;
  120.       case "prefservice:after-app-defaults":
  121.         this._onAppDefaults();
  122.         break;
  123.       case "final-ui-startup":
  124.         this._onProfileStartup();
  125.         break;
  126.       case "browser-delayed-startup-finished":
  127.         this._onFirstWindowLoaded();
  128.         Services.obs.removeObserver(this, "browser-delayed-startup-finished");
  129.         break;
  130.       case "sessionstore-windows-restored":
  131.         this._onBrowserStartup();
  132.         break;
  133.       case "browser:purge-session-history":
  134.         // reset the console service's error buffer
  135.         Services.console.logStringMessage(null); // clear the console (in case it's open)
  136.         Services.console.reset();
  137.         break;
  138.       case "quit-application-requested":
  139.         this._onQuitRequest(subject, data);
  140.         break;
  141.       case "quit-application-granted":
  142.         // This pref must be set here because SessionStore will use its value
  143.         // on quit-application.
  144.         this._setPrefToSaveSession();
  145.         break;
  146. //@line 193 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  147.       case "browser-lastwindow-close-requested":
  148.         // The application is not actually quitting, but the last full browser
  149.         // window is about to be closed.
  150.         this._onQuitRequest(subject, "lastwindow");
  151.         break;
  152.       case "browser-lastwindow-close-granted":
  153.         this._setPrefToSaveSession();
  154.         break;
  155. //@line 203 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  156.       case "weave:service:ready":
  157.         this._setSyncAutoconnectDelay();
  158.         break;
  159. //@line 207 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  160.       case "session-save":
  161.         this._setPrefToSaveSession(true);
  162.         subject.QueryInterface(Ci.nsISupportsPRBool);
  163.         subject.data = true;
  164.         break;
  165.       case "places-init-complete":
  166.         this._initPlaces();
  167.         Services.obs.removeObserver(this, "places-init-complete");
  168.         this._isPlacesInitObserver = false;
  169.         // no longer needed, since history was initialized completely.
  170.         Services.obs.removeObserver(this, "places-database-locked");
  171.         this._isPlacesLockedObserver = false;
  172.  
  173.         // Now apply distribution customized bookmarks.
  174.         // This should always run after Places initialization.
  175.         this._distributionCustomizer.applyBookmarks();
  176.         break;
  177.       case "places-database-locked":
  178.         this._isPlacesDatabaseLocked = true;
  179.         // Stop observing, so further attempts to load history service
  180.         // will not show the prompt.
  181.         Services.obs.removeObserver(this, "places-database-locked");
  182.         this._isPlacesLockedObserver = false;
  183.         break;
  184.       case "places-shutdown":
  185.         if (this._isPlacesShutdownObserver) {
  186.           Services.obs.removeObserver(this, "places-shutdown");
  187.           this._isPlacesShutdownObserver = false;
  188.         }
  189.         // places-shutdown is fired when the profile is about to disappear.
  190.         this._onProfileShutdown();
  191.         break;
  192.       case "idle":
  193.         if (this._idleService.idleTime > BOOKMARKS_BACKUP_IDLE_TIME * 1000)
  194.           this._backupBookmarks();
  195.         break;
  196.       case "distribution-customization-complete":
  197.         Services.obs.removeObserver(this, "distribution-customization-complete");
  198.         // Customization has finished, we don't need the customizer anymore.
  199.         delete this._distributionCustomizer;
  200.         break;
  201.       case "bookmarks-restore-success":
  202.       case "bookmarks-restore-failed":
  203.         Services.obs.removeObserver(this, "bookmarks-restore-success");
  204.         Services.obs.removeObserver(this, "bookmarks-restore-failed");
  205.         if (topic == "bookmarks-restore-success" && data == "html-initial")
  206.           this.ensurePlacesDefaultQueriesInitialized();
  207.         break;
  208.       case "browser-glue-test": // used by tests
  209.         if (data == "post-update-notification") {
  210.           if (Services.prefs.prefHasUserValue("app.update.postupdate"))
  211.             this._showUpdateNotification();
  212.         }
  213.         else if (data == "force-ui-migration") {
  214.           this._migrateUI();
  215.         }
  216.         else if (data == "force-distribution-customization") {
  217.           this._distributionCustomizer.applyPrefDefaults();
  218.           this._distributionCustomizer.applyCustomizations();
  219.           // To apply distribution bookmarks use "places-init-complete".
  220.         }
  221.         else if (data == "force-places-init") {
  222.           this._initPlaces();
  223.         }
  224.         break;
  225.     }
  226.   }, 
  227.  
  228.   // initialization (called on application startup) 
  229.   _init: function BG__init() {
  230.     let os = Services.obs;
  231.     os.addObserver(this, "xpcom-shutdown", false);
  232.     os.addObserver(this, "prefservice:after-app-defaults", false);
  233.     os.addObserver(this, "final-ui-startup", false);
  234.     os.addObserver(this, "browser-delayed-startup-finished", false);
  235.     os.addObserver(this, "sessionstore-windows-restored", false);
  236.     os.addObserver(this, "browser:purge-session-history", false);
  237.     os.addObserver(this, "quit-application-requested", false);
  238.     os.addObserver(this, "quit-application-granted", false);
  239. //@line 287 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  240.     os.addObserver(this, "browser-lastwindow-close-requested", false);
  241.     os.addObserver(this, "browser-lastwindow-close-granted", false);
  242. //@line 291 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  243.     os.addObserver(this, "weave:service:ready", false);
  244. //@line 293 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  245.     os.addObserver(this, "session-save", false);
  246.     os.addObserver(this, "places-init-complete", false);
  247.     this._isPlacesInitObserver = true;
  248.     os.addObserver(this, "places-database-locked", false);
  249.     this._isPlacesLockedObserver = true;
  250.     os.addObserver(this, "distribution-customization-complete", false);
  251.     os.addObserver(this, "places-shutdown", false);
  252.     this._isPlacesShutdownObserver = true;
  253.   },
  254.  
  255.   // cleanup (called on application shutdown)
  256.   _dispose: function BG__dispose() {
  257.     let os = Services.obs;
  258.     os.removeObserver(this, "xpcom-shutdown");
  259.     os.removeObserver(this, "prefservice:after-app-defaults");
  260.     os.removeObserver(this, "final-ui-startup");
  261.     os.removeObserver(this, "sessionstore-windows-restored");
  262.     os.removeObserver(this, "browser:purge-session-history");
  263.     os.removeObserver(this, "quit-application-requested");
  264.     os.removeObserver(this, "quit-application-granted");
  265. //@line 314 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  266.     os.removeObserver(this, "browser-lastwindow-close-requested");
  267.     os.removeObserver(this, "browser-lastwindow-close-granted");
  268. //@line 318 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  269.     os.removeObserver(this, "weave:service:ready", false);
  270. //@line 320 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  271.     os.removeObserver(this, "session-save");
  272.     if (this._isIdleObserver)
  273.       this._idleService.removeIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME);
  274.     if (this._isPlacesInitObserver)
  275.       os.removeObserver(this, "places-init-complete");
  276.     if (this._isPlacesLockedObserver)
  277.       os.removeObserver(this, "places-database-locked");
  278.     if (this._isPlacesShutdownObserver)
  279.       os.removeObserver(this, "places-shutdown");
  280.   },
  281.  
  282.   _onAppDefaults: function BG__onAppDefaults() {
  283.     // apply distribution customizations (prefs)
  284.     // other customizations are applied in _onProfileStartup()
  285.     this._distributionCustomizer.applyPrefDefaults();
  286.   },
  287.  
  288.   // profile startup handler (contains profile initialization routines)
  289.   _onProfileStartup: function BG__onProfileStartup() {
  290.     this._sanitizer.onStartup();
  291.     // check if we're in safe mode
  292.     if (Services.appinfo.inSafeMode) {
  293.       Services.ww.openWindow(null, "chrome://browser/content/safeMode.xul", 
  294.                              "_blank", "chrome,centerscreen,modal,resizable=no", null);
  295.     }
  296.  
  297.     // apply distribution customizations
  298.     // prefs are applied in _onAppDefaults()
  299.     this._distributionCustomizer.applyCustomizations();
  300.  
  301.     // handle any UI migration
  302.     this._migrateUI();
  303.  
  304.     Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
  305.   },
  306.  
  307.   // the first browser window has finished initializing
  308.   _onFirstWindowLoaded: function BG__onFirstWindowLoaded() {
  309. //@line 368 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  310.   },
  311.  
  312.   // profile shutdown handler (contains profile cleanup routines)
  313.   _onProfileShutdown: function BG__onProfileShutdown() {
  314.     this._shutdownPlaces();
  315.     this._sanitizer.onShutdown();
  316.   },
  317.  
  318.   // Browser startup complete. All initial windows have opened.
  319.   _onBrowserStartup: function BG__onBrowserStartup() {
  320.     // Show about:rights notification, if needed.
  321.     if (this._shouldShowRights()) {
  322.       this._showRightsNotification();
  323. //@line 386 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  324.     }
  325.  
  326.  
  327.     // Show update notification, if needed.
  328.     if (Services.prefs.prefHasUserValue("app.update.postupdate"))
  329.       this._showUpdateNotification();
  330.  
  331.     // Load the "more info" page for a locked places.sqlite
  332.     // This property is set earlier by places-database-locked topic.
  333.     if (this._isPlacesDatabaseLocked) {
  334.       this._showPlacesLockedNotificationBox();
  335.     }
  336.  
  337.     // If there are plugins installed that are outdated, and the user hasn't
  338.     // been warned about them yet, open the plugins update page.
  339.     if (Services.prefs.getBoolPref(PREF_PLUGINS_NOTIFYUSER))
  340.       this._showPluginUpdatePage();
  341.  
  342.     // For any add-ons that were installed disabled and can be enabled offer
  343.     // them to the user
  344.     var win = this.getMostRecentBrowserWindow();
  345.     var browser = win.gBrowser;
  346.     var changedIDs = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_INSTALLED);
  347.     AddonManager.getAddonsByIDs(changedIDs, function(aAddons) {
  348.       aAddons.forEach(function(aAddon) {
  349.         // If the add-on isn't user disabled or can't be enabled then skip it
  350.         if (!aAddon.userDisabled || !(aAddon.permissions & AddonManager.PERM_CAN_ENABLE))
  351.           return;
  352.  
  353.         browser.selectedTab = browser.addTab("about:newaddon?id=" + aAddon.id);
  354.       })
  355.     });
  356.   },
  357.  
  358.   _onQuitRequest: function BG__onQuitRequest(aCancelQuit, aQuitType) {
  359.     // If user has already dismissed quit request, then do nothing
  360.     if ((aCancelQuit instanceof Ci.nsISupportsPRBool) && aCancelQuit.data)
  361.       return;
  362.  
  363.     // There are several cases where we won't show a dialog here:
  364.     // 1. There is only 1 tab open in 1 window
  365.     // 2. The session will be restored at startup, indicated by
  366.     //    browser.startup.page == 3 or browser.sessionstore.resume_session_once == true
  367.     // 3. browser.warnOnQuit == false
  368.     // 4. The browser is currently in Private Browsing mode
  369.     //
  370.     // Otherwise these are the conditions and the associated dialogs that will be shown:
  371.     // 1. aQuitType == "lastwindow" or "quit" and browser.showQuitWarning == true
  372.     //    - The quit dialog will be shown
  373.     // 2. aQuitType == "restart" && browser.warnOnRestart == true
  374.     //    - The restart dialog will be shown
  375.     // 3. aQuitType == "lastwindow" && browser.tabs.warnOnClose == true
  376.     //    - The "closing multiple tabs" dialog will be shown
  377.     //
  378.     // aQuitType == "lastwindow" is overloaded. "lastwindow" is used to indicate
  379.     // "the last window is closing but we're not quitting (a non-browser window is open)"
  380.     // and also "we're quitting by closing the last window".
  381.  
  382.     var windowcount = 0;
  383.     var pagecount = 0;
  384.     var browserEnum = Services.wm.getEnumerator("navigator:browser");
  385.     while (browserEnum.hasMoreElements()) {
  386.       windowcount++;
  387.  
  388.       var browser = browserEnum.getNext();
  389.       var tabbrowser = browser.document.getElementById("content");
  390.       if (tabbrowser)
  391.         pagecount += tabbrowser.browsers.length - tabbrowser._numPinnedTabs;
  392.     }
  393.  
  394.     this._saveSession = false;
  395.     if (pagecount < 2)
  396.       return;
  397.  
  398.     if (!aQuitType)
  399.       aQuitType = "quit";
  400.  
  401.     // Never show a prompt inside private browsing mode
  402.     var inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
  403.                             getService(Ci.nsIPrivateBrowsingService).
  404.                             privateBrowsingEnabled;
  405.     if (inPrivateBrowsing)
  406.       return;
  407.  
  408.     var showPrompt = false;
  409.     var mostRecentBrowserWindow;
  410.  
  411.     // browser.warnOnQuit is a hidden global boolean to override all quit prompts
  412.     // browser.showQuitWarning specifically covers quitting
  413.     // browser.warnOnRestart specifically covers app-initiated restarts where we restart the app
  414.     // browser.tabs.warnOnClose is the global "warn when closing multiple tabs" pref
  415.  
  416.     var sessionWillBeRestored = Services.prefs.getIntPref("browser.startup.page") == 3 ||
  417.                                 Services.prefs.getBoolPref("browser.sessionstore.resume_session_once");
  418.     if (sessionWillBeRestored || !Services.prefs.getBoolPref("browser.warnOnQuit"))
  419.       return;
  420.  
  421.     // On last window close or quit && showQuitWarning, we want to show the
  422.     // quit warning.
  423.     if (aQuitType != "restart" && Services.prefs.getBoolPref("browser.showQuitWarning")) {
  424.       showPrompt = true;
  425.     }
  426.     else if (aQuitType == "restart" && Services.prefs.getBoolPref("browser.warnOnRestart")) {
  427.       showPrompt = true;
  428.     }
  429.     else if (aQuitType == "lastwindow") {
  430.       // If aQuitType is "lastwindow" and we aren't showing the quit warning,
  431.       // we should show the window closing warning instead. warnAboutClosing
  432.       // tabs checks browser.tabs.warnOnClose and returns if it's ok to close
  433.       // the window. It doesn't actually close the window.
  434.       mostRecentBrowserWindow = Services.wm.getMostRecentWindow("navigator:browser");
  435.       aCancelQuit.data = !mostRecentBrowserWindow.gBrowser.warnAboutClosingTabs(true);
  436.       return;
  437.     }
  438.  
  439.     if (!showPrompt)
  440.       return;
  441.  
  442.     var quitBundle = Services.strings.createBundle("chrome://browser/locale/quitDialog.properties");
  443.     var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
  444.  
  445.     var appName = brandBundle.GetStringFromName("brandShortName");
  446.     var quitTitleString = (aQuitType == "restart" ? "restart" : "quit") + "DialogTitle";
  447.     var quitDialogTitle = quitBundle.formatStringFromName(quitTitleString, [appName], 1);
  448.  
  449.     var message;
  450.     if (aQuitType == "restart")
  451.       message = quitBundle.formatStringFromName("messageRestart",
  452.                                                 [appName], 1);
  453.     else if (windowcount == 1)
  454.       message = quitBundle.formatStringFromName("messageNoWindows",
  455.                                                 [appName], 1);
  456.     else
  457.       message = quitBundle.formatStringFromName("message",
  458.                                                 [appName], 1);
  459.  
  460.     var promptService = Services.prompt;
  461.  
  462.     var flags = promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
  463.                 promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_1 +
  464.                 promptService.BUTTON_POS_0_DEFAULT;
  465.  
  466.     var neverAsk = {value:false};
  467.     var button0Title, button2Title;
  468.     var button1Title = quitBundle.GetStringFromName("cancelTitle");
  469.     var neverAskText = quitBundle.GetStringFromName("neverAsk");
  470.  
  471.     if (aQuitType == "restart")
  472.       button0Title = quitBundle.GetStringFromName("restartTitle");
  473.     else {
  474.       flags += promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2;
  475.       button0Title = quitBundle.GetStringFromName("saveTitle");
  476.       button2Title = quitBundle.GetStringFromName("quitTitle");
  477.     }
  478.  
  479.     // This wouldn't have been set above since we shouldn't be here for
  480.     // aQuitType == "lastwindow"
  481.     mostRecentBrowserWindow = Services.wm.getMostRecentWindow("navigator:browser");
  482.  
  483.     var buttonChoice =
  484.       promptService.confirmEx(mostRecentBrowserWindow, quitDialogTitle, message,
  485.                               flags, button0Title, button1Title, button2Title,
  486.                               neverAskText, neverAsk);
  487.  
  488.     switch (buttonChoice) {
  489.     case 2: // Quit
  490.       if (neverAsk.value)
  491.         Services.prefs.setBoolPref("browser.showQuitWarning", false);
  492.       break;
  493.     case 1: // Cancel
  494.       aCancelQuit.QueryInterface(Ci.nsISupportsPRBool);
  495.       aCancelQuit.data = true;
  496.       break;
  497.     case 0: // Save & Quit
  498.       this._saveSession = true;
  499.       if (neverAsk.value) {
  500.         if (aQuitType == "restart")
  501.           Services.prefs.setBoolPref("browser.warnOnRestart", false);
  502.         else {
  503.           // always save state when shutting down
  504.           Services.prefs.setIntPref("browser.startup.page", 3);
  505.         }
  506.       }
  507.       break;
  508.     }
  509.   },
  510.  
  511.   /*
  512.    * _shouldShowRights - Determines if the user should be shown the
  513.    * about:rights notification. The notification should *not* be shown if
  514.    * we've already shown the current version, or if the override pref says to
  515.    * never show it. The notification *should* be shown if it's never been seen
  516.    * before, if a newer version is available, or if the override pref says to
  517.    * always show it.
  518.    */
  519.   _shouldShowRights: function BG__shouldShowRights() {
  520.     // Look for an unconditional override pref. If set, do what it says.
  521.     // (true --> never show, false --> always show)
  522.     try {
  523.       return !Services.prefs.getBoolPref("browser.rights.override");
  524.     } catch (e) { }
  525.     // Ditto, for the legacy EULA pref.
  526.     try {
  527.       return !Services.prefs.getBoolPref("browser.EULA.override");
  528.     } catch (e) { }
  529.  
  530. //@line 593 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  531.     // Non-official builds shouldn't shouldn't show the notification.
  532.     return false;
  533. //@line 596 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  534.  
  535.     // Look to see if the user has seen the current version or not.
  536.     var currentVersion = Services.prefs.getIntPref("browser.rights.version");
  537.     try {
  538.       return !Services.prefs.getBoolPref("browser.rights." + currentVersion + ".shown");
  539.     } catch (e) { }
  540.  
  541.     // Legacy: If the user accepted a EULA, we won't annoy them with the
  542.     // equivalent about:rights page until the version changes.
  543.     try {
  544.       return !Services.prefs.getBoolPref("browser.EULA." + currentVersion + ".accepted");
  545.     } catch (e) { }
  546.  
  547.     // We haven't shown the notification before, so do so now.
  548.     return true;
  549.   },
  550.  
  551.   _showRightsNotification: function BG__showRightsNotification() {
  552.     // Stick the notification onto the selected tab of the active browser window.
  553.     var win = this.getMostRecentBrowserWindow();
  554.     var browser = win.gBrowser; // for closure in notification bar callback
  555.     var notifyBox = browser.getNotificationBox();
  556.  
  557.     var brandBundle  = Services.strings.createBundle("chrome://branding/locale/brand.properties");
  558.     var rightsBundle = Services.strings.createBundle("chrome://global/locale/aboutRights.properties");
  559.  
  560.     var buttonLabel      = rightsBundle.GetStringFromName("buttonLabel");
  561.     var buttonAccessKey  = rightsBundle.GetStringFromName("buttonAccessKey");
  562.     var productName      = brandBundle.GetStringFromName("brandFullName");
  563.     var notifyRightsText = rightsBundle.formatStringFromName("notifyRightsText", [productName], 1);
  564.  
  565.     var buttons = [
  566.                     {
  567.                       label:     buttonLabel,
  568.                       accessKey: buttonAccessKey,
  569.                       popup:     null,
  570.                       callback: function(aNotificationBar, aButton) {
  571.                         browser.selectedTab = browser.addTab("about:rights");
  572.                       }
  573.                     }
  574.                   ];
  575.  
  576.     // Set pref to indicate we've shown the notification.
  577.     var currentVersion = Services.prefs.getIntPref("browser.rights.version");
  578.     Services.prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true);
  579.  
  580.     var notification = notifyBox.appendNotification(notifyRightsText, "about-rights", null, notifyBox.PRIORITY_INFO_LOW, buttons);
  581.     notification.persistence = -1; // Until user closes it
  582.   },
  583.  
  584.   _showUpdateNotification: function BG__showUpdateNotification() {
  585.     Services.prefs.clearUserPref("app.update.postupdate");
  586.  
  587.     var um = Cc["@mozilla.org/updates/update-manager;1"].
  588.              getService(Ci.nsIUpdateManager);
  589.     try {
  590.       // If the updates.xml file is deleted then getUpdateAt will throw.
  591.       var update = um.getUpdateAt(0).QueryInterface(Ci.nsIPropertyBag);
  592.     }
  593.     catch (e) {
  594.       // This should never happen.
  595.       Cu.reportError("Unable to find update: " + e);
  596.       return;
  597.     }
  598.  
  599.     var actions = update.getProperty("actions");
  600.     if (!actions || actions.indexOf("silent") != -1)
  601.       return;
  602.  
  603.     var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
  604.                     getService(Ci.nsIURLFormatter);
  605.     var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
  606.     var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
  607.     var appName = brandBundle.GetStringFromName("brandShortName");
  608.  
  609.     function getNotifyString(aPropData) {
  610.       var propValue = update.getProperty(aPropData.propName);
  611.       if (!propValue) {
  612.         if (aPropData.prefName)
  613.           propValue = formatter.formatURLPref(aPropData.prefName);
  614.         else if (aPropData.stringParams)
  615.           propValue = browserBundle.formatStringFromName(aPropData.stringName,
  616.                                                          aPropData.stringParams,
  617.                                                          aPropData.stringParams.length);
  618.         else
  619.           propValue = browserBundle.GetStringFromName(aPropData.stringName);
  620.       }
  621.       return propValue;
  622.     }
  623.  
  624.     if (actions.indexOf("showNotification") != -1) {
  625.       let text = getNotifyString({propName: "notificationText",
  626.                                   stringName: "puNotifyText",
  627.                                   stringParams: [appName]});
  628.       let url = getNotifyString({propName: "notificationURL",
  629.                                  prefName: "startup.homepage_override_url"});
  630.       let label = getNotifyString({propName: "notificationButtonLabel",
  631.                                    stringName: "pu.notifyButton.label"});
  632.       let key = getNotifyString({propName: "notificationButtonAccessKey",
  633.                                  stringName: "pu.notifyButton.accesskey"});
  634.  
  635.       let win = this.getMostRecentBrowserWindow();
  636.       let browser = win.gBrowser; // for closure in notification bar callback
  637.       let notifyBox = browser.getNotificationBox();
  638.  
  639.       let buttons = [
  640.                       {
  641.                         label:     label,
  642.                         accessKey: key,
  643.                         popup:     null,
  644.                         callback: function(aNotificationBar, aButton) {
  645.                           browser.selectedTab = browser.addTab(url);
  646.                         }
  647.                       }
  648.                     ];
  649.  
  650.       let notification = notifyBox.appendNotification(text, "post-update-notification",
  651.                                                       null, notifyBox.PRIORITY_INFO_LOW,
  652.                                                       buttons);
  653.       notification.persistence = -1; // Until user closes it
  654.     }
  655.  
  656.     if (actions.indexOf("showAlert") == -1)
  657.       return;
  658.  
  659.     let notifier;
  660.     try {
  661.       notifier = Cc["@mozilla.org/alerts-service;1"].
  662.                  getService(Ci.nsIAlertsService);
  663.     }
  664.     catch (e) {
  665.       // nsIAlertsService is not available for this platform
  666.       return;
  667.     }
  668.  
  669.     let title = getNotifyString({propName: "alertTitle",
  670.                                  stringName: "puAlertTitle",
  671.                                  stringParams: [appName]});
  672.     let text = getNotifyString({propName: "alertText",
  673.                                 stringName: "puAlertText",
  674.                                 stringParams: [appName]});
  675.     let url = getNotifyString({propName: "alertURL",
  676.                                prefName: "startup.homepage_override_url"});
  677.  
  678.     var self = this;
  679.     function clickCallback(subject, topic, data) {
  680.       // This callback will be called twice but only once with this topic
  681.       if (topic != "alertclickcallback")
  682.         return;
  683.       let win = self.getMostRecentBrowserWindow();
  684.       let browser = win.gBrowser;
  685.       browser.selectedTab = browser.addTab(data);
  686.     }
  687.  
  688.     try {
  689.       // This will throw NS_ERROR_NOT_AVAILABLE if the notification cannot
  690.       // be displayed per the idl.
  691.       notifier.showAlertNotification("post-update-notification", title, text,
  692.                                      true, url, clickCallback);
  693.     }
  694.     catch (e) {
  695.     }
  696.   },
  697.  
  698. //@line 838 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  699.  
  700.   _showPluginUpdatePage: function BG__showPluginUpdatePage() {
  701.     Services.prefs.setBoolPref(PREF_PLUGINS_NOTIFYUSER, false);
  702.  
  703.     var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
  704.                     getService(Ci.nsIURLFormatter);
  705.     var updateUrl = formatter.formatURLPref(PREF_PLUGINS_UPDATEURL);
  706.  
  707.     var win = this.getMostRecentBrowserWindow();
  708.     var browser = win.gBrowser;
  709.     browser.selectedTab = browser.addTab(updateUrl);
  710.   },
  711.  
  712.   /**
  713.    * Initialize Places
  714.    * - imports the bookmarks html file if bookmarks database is empty, try to
  715.    *   restore bookmarks from a JSON backup if the backend indicates that the
  716.    *   database was corrupt.
  717.    *
  718.    * These prefs can be set up by the frontend:
  719.    *
  720.    * WARNING: setting these preferences to true will overwite existing bookmarks
  721.    *
  722.    * - browser.places.importBookmarksHTML
  723.    *   Set to true will import the bookmarks.html file from the profile folder.
  724.    * - browser.places.smartBookmarksVersion
  725.    *   Set during HTML import to indicate that Smart Bookmarks were created.
  726.    *   Set to -1 to disable Smart Bookmarks creation.
  727.    *   Set to 0 to restore current Smart Bookmarks.
  728.    * - browser.bookmarks.restore_default_bookmarks
  729.    *   Set to true by safe-mode dialog to indicate we must restore default
  730.    *   bookmarks.
  731.    */
  732.   _initPlaces: function BG__initPlaces() {
  733.     // We must instantiate the history service since it will tell us if we
  734.     // need to import or restore bookmarks due to first-run, corruption or
  735.     // forced migration (due to a major schema change).
  736.     // If the database is corrupt or has been newly created we should
  737.     // import bookmarks.
  738.     var dbStatus = PlacesUtils.history.databaseStatus;
  739.     var importBookmarks = dbStatus == PlacesUtils.history.DATABASE_STATUS_CREATE ||
  740.                           dbStatus == PlacesUtils.history.DATABASE_STATUS_CORRUPT;
  741.  
  742.     if (dbStatus == PlacesUtils.history.DATABASE_STATUS_CREATE) {
  743.       // If the database has just been created, but we already have any
  744.       // bookmark, this is not the initial import.  This can happen after a
  745.       // migration from a different browser since migrators run before us.
  746.       // In such a case we should not import, unless some pref has been set.
  747.       if (PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.bookmarksMenuFolderId, 0) != -1 ||
  748.           PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0) != -1)
  749.         importBookmarks = false;
  750.     }
  751.  
  752.     // Check if user or an extension has required to import bookmarks.html
  753.     var importBookmarksHTML = false;
  754.     try {
  755.       importBookmarksHTML =
  756.         Services.prefs.getBoolPref("browser.places.importBookmarksHTML");
  757.       if (importBookmarksHTML)
  758.         importBookmarks = true;
  759.     } catch(ex) {}
  760.  
  761.     // Check if Safe Mode or the user has required to restore bookmarks from
  762.     // default profile's bookmarks.html
  763.     var restoreDefaultBookmarks = false;
  764.     try {
  765.       restoreDefaultBookmarks =
  766.         Services.prefs.getBoolPref("browser.bookmarks.restore_default_bookmarks");
  767.       if (restoreDefaultBookmarks) {
  768.         // Ensure that we already have a bookmarks backup for today.
  769.         this._backupBookmarks();
  770.         importBookmarks = true;
  771.       }
  772.     } catch(ex) {}
  773.  
  774.     // If the user did not require to restore default bookmarks, or import
  775.     // from bookmarks.html, we will try to restore from JSON
  776.     if (importBookmarks && !restoreDefaultBookmarks && !importBookmarksHTML) {
  777.       // get latest JSON backup
  778.       var bookmarksBackupFile = PlacesUtils.backups.getMostRecent("json");
  779.       if (bookmarksBackupFile) {
  780.         // restore from JSON backup
  781.         PlacesUtils.restoreBookmarksFromJSONFile(bookmarksBackupFile);
  782.         importBookmarks = false;
  783.       }
  784.       else {
  785.         // We have created a new database but we don't have any backup available
  786.         importBookmarks = true;
  787.         var dirService = Cc["@mozilla.org/file/directory_service;1"].
  788.                          getService(Ci.nsIProperties);
  789.         var bookmarksHTMLFile = dirService.get("BMarks", Ci.nsILocalFile);
  790.         if (bookmarksHTMLFile.exists()) {
  791.           // If bookmarks.html is available in current profile import it...
  792.           importBookmarksHTML = true;
  793.         }
  794.         else {
  795.           // ...otherwise we will restore defaults
  796.           restoreDefaultBookmarks = true;
  797.         }
  798.       }
  799.     }
  800.  
  801.     // If bookmarks are not imported, then initialize smart bookmarks.  This
  802.     // happens during a common startup.
  803.     // Otherwise, if any kind of import runs, smart bookmarks creation should be
  804.     // delayed till the import operations has finished.  Not doing so would
  805.     // cause them to be overwritten by the newly imported bookmarks.
  806.     if (!importBookmarks) {
  807.       this.ensurePlacesDefaultQueriesInitialized();
  808.     }
  809.     else {
  810.       // An import operation is about to run.
  811.       // Don't try to recreate smart bookmarks if autoExportHTML is true or
  812.       // smart bookmarks are disabled.
  813.       var autoExportHTML = false;
  814.       try {
  815.         autoExportHTML = Services.prefs.getBoolPref("browser.bookmarks.autoExportHTML");
  816.       } catch(ex) {}
  817.       var smartBookmarksVersion = 0;
  818.       try {
  819.         smartBookmarksVersion = Services.prefs.getIntPref("browser.places.smartBookmarksVersion");
  820.       } catch(ex) {}
  821.       if (!autoExportHTML && smartBookmarksVersion != -1)
  822.         Services.prefs.setIntPref("browser.places.smartBookmarksVersion", 0);
  823.  
  824.       // Get bookmarks.html file location
  825.       var dirService = Cc["@mozilla.org/file/directory_service;1"].
  826.                        getService(Ci.nsIProperties);
  827.  
  828.       var bookmarksURI = null;
  829.       if (restoreDefaultBookmarks) {
  830.         // User wants to restore bookmarks.html file from default profile folder
  831.         bookmarksURI = NetUtil.newURI("resource:///defaults/profile/bookmarks.html");
  832.       }
  833.       else {
  834.         var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile);
  835.         if (bookmarksFile.exists())
  836.           bookmarksURI = NetUtil.newURI(bookmarksFile);
  837.       }
  838.  
  839.       if (bookmarksURI) {
  840.         // Add an import observer.  It will ensure that smart bookmarks are
  841.         // created once the operation is complete.
  842.         Services.obs.addObserver(this, "bookmarks-restore-success", false);
  843.         Services.obs.addObserver(this, "bookmarks-restore-failed", false);
  844.  
  845.         // Import from bookmarks.html file.
  846.         try {
  847.           var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
  848.                          getService(Ci.nsIPlacesImportExportService);
  849.           importer.importHTMLFromURI(bookmarksURI, true /* overwrite existing */);
  850.         } catch (err) {
  851.           // Report the error, but ignore it.
  852.           Cu.reportError("Bookmarks.html file could be corrupt. " + err);
  853.           Services.obs.removeObserver(this, "bookmarks-restore-success");
  854.           Services.obs.removeObserver(this, "bookmarks-restore-failed");
  855.         }
  856.       }
  857.       else
  858.         Cu.reportError("Unable to find bookmarks.html file.");
  859.  
  860.       // Reset preferences, so we won't try to import again at next run
  861.       if (importBookmarksHTML)
  862.         Services.prefs.setBoolPref("browser.places.importBookmarksHTML", false);
  863.       if (restoreDefaultBookmarks)
  864.         Services.prefs.setBoolPref("browser.bookmarks.restore_default_bookmarks",
  865.                                    false);
  866.     }
  867.  
  868.     // Initialize bookmark archiving on idle.
  869.     // Once a day, either on idle or shutdown, bookmarks are backed up.
  870.     if (!this._isIdleObserver) {
  871.       this._idleService.addIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME);
  872.       this._isIdleObserver = true;
  873.     }
  874.   },
  875.  
  876.   /**
  877.    * Places shut-down tasks
  878.    * - back up bookmarks if needed.
  879.    * - export bookmarks as HTML, if so configured.
  880.    *
  881.    * Note: quit-application-granted notification is received twice
  882.    *       so replace this method with a no-op when first called.
  883.    */
  884.   _shutdownPlaces: function BG__shutdownPlaces() {
  885.     if (this._isIdleObserver) {
  886.       this._idleService.removeIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME);
  887.       this._isIdleObserver = false;
  888.     }
  889.     this._backupBookmarks();
  890.  
  891.     // Backup bookmarks to bookmarks.html to support apps that depend
  892.     // on the legacy format.
  893.     var autoExportHTML = false;
  894.     try {
  895.       autoExportHTML = Services.prefs.getBoolPref("browser.bookmarks.autoExportHTML");
  896.     } catch(ex) { /* Don't export */ }
  897.  
  898.     if (autoExportHTML) {
  899.       Cc["@mozilla.org/browser/places/import-export-service;1"].
  900.         getService(Ci.nsIPlacesImportExportService).
  901.         backupBookmarksFile();
  902.     }
  903.   },
  904.  
  905.   /**
  906.    * Backup bookmarks if needed.
  907.    */
  908.   _backupBookmarks: function BG__backupBookmarks() {
  909.     let lastBackupFile = PlacesUtils.backups.getMostRecent();
  910.  
  911.     // Backup bookmarks if there are no backups or the maximum interval between
  912.     // backups elapsed.
  913.     if (!lastBackupFile ||
  914.         new Date() - PlacesUtils.backups.getDateForFile(lastBackupFile) > BOOKMARKS_BACKUP_INTERVAL) {
  915.       let maxBackups = BOOKMARKS_BACKUP_MAX_BACKUPS;
  916.       try {
  917.         maxBackups = Services.prefs.getIntPref("browser.bookmarks.max_backups");
  918.       }
  919.       catch(ex) { /* Use default. */ }
  920.  
  921.       PlacesUtils.backups.create(maxBackups); // Don't force creation.
  922.     }
  923.   },
  924.  
  925.   /**
  926.    * Show the notificationBox for a locked places database.
  927.    */
  928.   _showPlacesLockedNotificationBox: function BG__showPlacesLockedNotificationBox() {
  929.     var brandBundle  = Services.strings.createBundle("chrome://branding/locale/brand.properties");
  930.     var applicationName = brandBundle.GetStringFromName("brandShortName");
  931.     var placesBundle = Services.strings.createBundle("chrome://browser/locale/places/places.properties");
  932.     var title = placesBundle.GetStringFromName("lockPrompt.title");
  933.     var text = placesBundle.formatStringFromName("lockPrompt.text", [applicationName], 1);
  934.     var buttonText = placesBundle.GetStringFromName("lockPromptInfoButton.label");
  935.     var accessKey = placesBundle.GetStringFromName("lockPromptInfoButton.accessKey");
  936.  
  937.     var helpTopic = "places-locked";
  938.     var url = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
  939.               getService(Components.interfaces.nsIURLFormatter).
  940.               formatURLPref("app.support.baseURL");
  941.     url += helpTopic;
  942.  
  943.     var browser = this.getMostRecentBrowserWindow().gBrowser;
  944.  
  945.     var buttons = [
  946.                     {
  947.                       label:     buttonText,
  948.                       accessKey: accessKey,
  949.                       popup:     null,
  950.                       callback:  function(aNotificationBar, aButton) {
  951.                         browser.selectedTab = browser.addTab(url);
  952.                       }
  953.                     }
  954.                   ];
  955.  
  956.     var notifyBox = browser.getNotificationBox();
  957.     var notification = notifyBox.appendNotification(text, title, null,
  958.                                                     notifyBox.PRIORITY_CRITICAL_MEDIUM,
  959.                                                     buttons);
  960.     notification.persistence = -1; // Until user closes it
  961.   },
  962.  
  963.   _migrateUI: function BG__migrateUI() {
  964.     const UI_VERSION = 5;
  965.     const BROWSER_DOCURL = "chrome://browser/content/browser.xul#";
  966.     let currentUIVersion = 0;
  967.     try {
  968.       currentUIVersion = Services.prefs.getIntPref("browser.migration.version");
  969.     } catch(ex) {}
  970.     if (currentUIVersion >= UI_VERSION)
  971.       return;
  972.  
  973.     this._rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
  974.     this._dataSource = this._rdf.GetDataSource("rdf:local-store");
  975.     this._dirty = false;
  976.  
  977.     if (currentUIVersion < 1) {
  978.       // this code should always migrate pre-FF3 profiles to the current UI state
  979.       let currentsetResource = this._rdf.GetResource("currentset");
  980.       let toolbars = ["nav-bar", "toolbar-menubar", "PersonalToolbar"];
  981.       for (let i = 0; i < toolbars.length; i++) {
  982.         let toolbar = this._rdf.GetResource(BROWSER_DOCURL + toolbars[i]);
  983.         let currentset = this._getPersist(toolbar, currentsetResource);
  984.         if (!currentset) {
  985.           // toolbar isn't customized
  986.           if (i == 0)
  987.             // new button is in the defaultset, nothing to migrate
  988.             break;
  989.           continue;
  990.         }
  991.         if (/(?:^|,)unified-back-forward-button(?:$|,)/.test(currentset))
  992.           // new button is already there, nothing to migrate
  993.           break;
  994.         if (/(?:^|,)back-button(?:$|,)/.test(currentset)) {
  995.           let newset = currentset.replace(/(^|,)back-button($|,)/,
  996.                                           "$1unified-back-forward-button,back-button$2")
  997.           this._setPersist(toolbar, currentsetResource, newset);
  998.           // done migrating
  999.           break;
  1000.         }
  1001.       }
  1002.     }
  1003.  
  1004.     if (currentUIVersion < 2) {
  1005.       // This code adds the customizable bookmarks button.
  1006.       let currentsetResource = this._rdf.GetResource("currentset");
  1007.       let toolbarResource = this._rdf.GetResource(BROWSER_DOCURL + "nav-bar");
  1008.       let currentset = this._getPersist(toolbarResource, currentsetResource);
  1009.       // Need to migrate only if toolbar is customized and the element is not found.
  1010.       if (currentset &&
  1011.           currentset.indexOf("bookmarks-menu-button-container") == -1) {
  1012.         if (currentset.indexOf("fullscreenflex") != -1) {
  1013.           currentset = currentset.replace(/(^|,)fullscreenflex($|,)/,
  1014.                                           "$1bookmarks-menu-button-container,fullscreenflex$2")
  1015.         }
  1016.         else {
  1017.           currentset += ",bookmarks-menu-button-container";
  1018.         }
  1019.         this._setPersist(toolbarResource, currentsetResource, currentset);
  1020.       }
  1021.     }
  1022.  
  1023.     if (currentUIVersion < 3) {
  1024.       // This code merges the reload/stop/go button into the url bar.
  1025.       let currentsetResource = this._rdf.GetResource("currentset");
  1026.       let toolbarResource = this._rdf.GetResource(BROWSER_DOCURL + "nav-bar");
  1027.       let currentset = this._getPersist(toolbarResource, currentsetResource);
  1028.       // Need to migrate only if toolbar is customized and all 3 elements are found.
  1029.       if (currentset &&
  1030.           currentset.indexOf("reload-button") != -1 &&
  1031.           currentset.indexOf("stop-button") != -1 &&
  1032.           currentset.indexOf("urlbar-container") != -1 &&
  1033.           currentset.indexOf("urlbar-container,reload-button,stop-button") == -1) {
  1034.         currentset = currentset.replace(/(^|,)reload-button($|,)/, "$1$2")
  1035.                                .replace(/(^|,)stop-button($|,)/, "$1$2")
  1036.                                .replace(/(^|,)urlbar-container($|,)/,
  1037.                                         "$1urlbar-container,reload-button,stop-button$2");
  1038.         this._setPersist(toolbarResource, currentsetResource, currentset);
  1039.       }
  1040.     }
  1041.  
  1042.     if (currentUIVersion < 4) {
  1043.       // This code moves the home button to the immediate left of the bookmarks menu button.
  1044.       let currentsetResource = this._rdf.GetResource("currentset");
  1045.       let toolbarResource = this._rdf.GetResource(BROWSER_DOCURL + "nav-bar");
  1046.       let currentset = this._getPersist(toolbarResource, currentsetResource);
  1047.       // Need to migrate only if toolbar is customized and the elements are found.
  1048.       if (currentset &&
  1049.           currentset.indexOf("home-button") != -1 &&
  1050.           currentset.indexOf("bookmarks-menu-button-container") != -1) {
  1051.         currentset = currentset.replace(/(^|,)home-button($|,)/, "$1$2")
  1052.                                .replace(/(^|,)bookmarks-menu-button-container($|,)/,
  1053.                                         "$1home-button,bookmarks-menu-button-container$2");
  1054.         this._setPersist(toolbarResource, currentsetResource, currentset);
  1055.       }
  1056.     }
  1057.  
  1058.     if (currentUIVersion < 5) {
  1059.       // This code uncollapses PersonalToolbar if its collapsed status is not
  1060.       // persisted, and user customized it or changed default bookmarks.
  1061.       let toolbarResource = this._rdf.GetResource(BROWSER_DOCURL + "PersonalToolbar");
  1062.       let collapsedResource = this._rdf.GetResource("collapsed");
  1063.       let collapsed = this._getPersist(toolbarResource, collapsedResource);
  1064.       // If the user does not have a persisted value for the toolbar's
  1065.       // "collapsed" attribute, try to determine whether it's customized.
  1066.       if (collapsed === null) {
  1067.         // We consider the toolbar customized if it has more than
  1068.         // 3 children, or if it has a persisted currentset value.
  1069.         let currentsetResource = this._rdf.GetResource("currentset");
  1070.         let toolbarIsCustomized = !!this._getPersist(toolbarResource,
  1071.                                                      currentsetResource);
  1072.         function getToolbarFolderCount() {
  1073.           let toolbarFolder =
  1074.             PlacesUtils.getFolderContents(PlacesUtils.toolbarFolderId).root;
  1075.           let toolbarChildCount = toolbarFolder.childCount;
  1076.           toolbarFolder.containerOpen = false;
  1077.           return toolbarChildCount;
  1078.         }
  1079.  
  1080.         if (toolbarIsCustomized || getToolbarFolderCount() > 3) {
  1081.           this._setPersist(toolbarResource, collapsedResource, "false");
  1082.         }
  1083.       }
  1084.     }
  1085.  
  1086.     if (this._dirty)
  1087.       this._dataSource.QueryInterface(Ci.nsIRDFRemoteDataSource).Flush();
  1088.  
  1089.     delete this._rdf;
  1090.     delete this._dataSource;
  1091.  
  1092.     // Update the migration version.
  1093.     Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
  1094.   },
  1095.  
  1096.   _getPersist: function BG__getPersist(aSource, aProperty) {
  1097.     var target = this._dataSource.GetTarget(aSource, aProperty, true);
  1098.     if (target instanceof Ci.nsIRDFLiteral)
  1099.       return target.Value;
  1100.     return null;
  1101.   },
  1102.  
  1103.   _setPersist: function BG__setPersist(aSource, aProperty, aTarget) {
  1104.     this._dirty = true;
  1105.     try {
  1106.       var oldTarget = this._dataSource.GetTarget(aSource, aProperty, true);
  1107.       if (oldTarget) {
  1108.         if (aTarget)
  1109.           this._dataSource.Change(aSource, aProperty, oldTarget, this._rdf.GetLiteral(aTarget));
  1110.         else
  1111.           this._dataSource.Unassert(aSource, aProperty, oldTarget);
  1112.       }
  1113.       else {
  1114.         this._dataSource.Assert(aSource, aProperty, this._rdf.GetLiteral(aTarget), true);
  1115.       }
  1116.  
  1117.       // Add the entry to the persisted set for this document if it's not there.
  1118.       // This code is mostly borrowed from nsXULDocument::Persist.
  1119.       let docURL = aSource.ValueUTF8.split("#")[0];
  1120.       let docResource = this._rdf.GetResource(docURL);
  1121.       let persistResource = this._rdf.GetResource("http://home.netscape.com/NC-rdf#persist");
  1122.       if (!this._dataSource.HasAssertion(docResource, persistResource, aSource, true)) {
  1123.         this._dataSource.Assert(docResource, persistResource, aSource, true);
  1124.       }
  1125.     }
  1126.     catch(ex) {}
  1127.   },
  1128.  
  1129.   // ------------------------------
  1130.   // public nsIBrowserGlue members
  1131.   // ------------------------------
  1132.  
  1133.   sanitize: function BG_sanitize(aParentWindow) {
  1134.     this._sanitizer.sanitize(aParentWindow);
  1135.   },
  1136.  
  1137.   ensurePlacesDefaultQueriesInitialized:
  1138.   function BG_ensurePlacesDefaultQueriesInitialized() {
  1139.     // This is actual version of the smart bookmarks, must be increased every
  1140.     // time smart bookmarks change.
  1141.     // When adding a new smart bookmark below, its newInVersion property must
  1142.     // be set to the version it has been added in, we will compare its value
  1143.     // to users' smartBookmarksVersion and add new smart bookmarks without
  1144.     // recreating old deleted ones.
  1145.     const SMART_BOOKMARKS_VERSION = 2;
  1146.     const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
  1147.     const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion";
  1148.  
  1149.     // TODO bug 399268: should this be a pref?
  1150.     const MAX_RESULTS = 10;
  1151.  
  1152.     // Get current smart bookmarks version.  If not set, create them.
  1153.     let smartBookmarksCurrentVersion = 0;
  1154.     try {
  1155.       smartBookmarksCurrentVersion = Services.prefs.getIntPref(SMART_BOOKMARKS_PREF);
  1156.     } catch(ex) {}
  1157.  
  1158.     // If version is current or smart bookmarks are disabled, just bail out.
  1159.     if (smartBookmarksCurrentVersion == -1 ||
  1160.         smartBookmarksCurrentVersion >= SMART_BOOKMARKS_VERSION) {
  1161.       return;
  1162.     }
  1163.  
  1164.     let batch = {
  1165.       runBatched: function BG_EPDQI_runBatched() {
  1166.         let menuIndex = 0;
  1167.         let toolbarIndex = 0;
  1168.         let bundle = Services.strings.createBundle("chrome://browser/locale/places/places.properties");
  1169.  
  1170.         let smartBookmarks = {
  1171.           MostVisited: {
  1172.             title: bundle.GetStringFromName("mostVisitedTitle"),
  1173.             uri: NetUtil.newURI("place:redirectsMode=" +
  1174.                                 Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET +
  1175.                                 "&sort=" +
  1176.                                 Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
  1177.                                 "&maxResults=" + MAX_RESULTS),
  1178.             parent: PlacesUtils.toolbarFolderId,
  1179.             position: toolbarIndex++,
  1180.             newInVersion: 1
  1181.           },
  1182.           RecentlyBookmarked: {
  1183.             title: bundle.GetStringFromName("recentlyBookmarkedTitle"),
  1184.             uri: NetUtil.newURI("place:folder=BOOKMARKS_MENU" +
  1185.                                 "&folder=UNFILED_BOOKMARKS" +
  1186.                                 "&folder=TOOLBAR" +
  1187.                                 "&queryType=" +
  1188.                                 Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
  1189.                                 "&sort=" +
  1190.                                 Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
  1191.                                 "&excludeItemIfParentHasAnnotation=livemark%2FfeedURI" +
  1192.                                 "&maxResults=" + MAX_RESULTS +
  1193.                                 "&excludeQueries=1"),
  1194.             parent: PlacesUtils.bookmarksMenuFolderId,
  1195.             position: menuIndex++,
  1196.             newInVersion: 1
  1197.           },
  1198.           RecentTags: {
  1199.             title: bundle.GetStringFromName("recentTagsTitle"),
  1200.             uri: NetUtil.newURI("place:"+
  1201.                                 "type=" +
  1202.                                 Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY +
  1203.                                 "&sort=" +
  1204.                                 Ci.nsINavHistoryQueryOptions.SORT_BY_LASTMODIFIED_DESCENDING +
  1205.                                 "&maxResults=" + MAX_RESULTS),
  1206.             parent: PlacesUtils.bookmarksMenuFolderId,
  1207.             position: menuIndex++,
  1208.             newInVersion: 1
  1209.           },
  1210.         };
  1211.  
  1212.         // Set current itemId, parent and position if Smart Bookmark exists,
  1213.         // we will use these informations to create the new version at the same
  1214.         // position.
  1215.         let smartBookmarkItemIds = PlacesUtils.annotations.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO);
  1216.         smartBookmarkItemIds.forEach(function (itemId) {
  1217.           let queryId = PlacesUtils.annotations.getItemAnnotation(itemId, SMART_BOOKMARKS_ANNO);
  1218.           if (queryId in smartBookmarks) {
  1219.             let smartBookmark = smartBookmarks[queryId];
  1220.             smartBookmarks[queryId].itemId = itemId;
  1221.             smartBookmarks[queryId].parent = PlacesUtils.bookmarks.getFolderIdForItem(itemId);
  1222.             smartBookmarks[queryId].position = PlacesUtils.bookmarks.getItemIndex(itemId);
  1223.           }
  1224.           else {
  1225.             // We don't remove old Smart Bookmarks because user could still
  1226.             // find them useful, or could have personalized them.
  1227.             // Instead we remove the Smart Bookmark annotation.
  1228.             PlacesUtils.annotations.removeItemAnnotation(itemId, SMART_BOOKMARKS_ANNO);
  1229.           }
  1230.         });
  1231.  
  1232.         for (let queryId in smartBookmarks) {
  1233.           let smartBookmark = smartBookmarks[queryId];
  1234.  
  1235.           // We update or create only changed or new smart bookmarks.
  1236.           // Also we respect user choices, so we won't try to create a smart
  1237.           // bookmark if it has been removed.
  1238.           if (smartBookmarksCurrentVersion > 0 &&
  1239.               smartBookmark.newInVersion <= smartBookmarksCurrentVersion &&
  1240.               !smartBookmark.itemId)
  1241.             continue;
  1242.  
  1243.           // Remove old version of the smart bookmark if it exists, since it
  1244.           // will be replaced in place.
  1245.           if (smartBookmark.itemId) {
  1246.             PlacesUtils.bookmarks.removeItem(smartBookmark.itemId);
  1247.           }
  1248.  
  1249.           // Create the new smart bookmark and store its updated itemId.
  1250.           smartBookmark.itemId =
  1251.             PlacesUtils.bookmarks.insertBookmark(smartBookmark.parent,
  1252.                                                  smartBookmark.uri,
  1253.                                                  smartBookmark.position,
  1254.                                                  smartBookmark.title);
  1255.           PlacesUtils.annotations.setItemAnnotation(smartBookmark.itemId,
  1256.                                                     SMART_BOOKMARKS_ANNO,
  1257.                                                     queryId, 0,
  1258.                                                     PlacesUtils.annotations.EXPIRE_NEVER);
  1259.         }
  1260.  
  1261.         // If we are creating all Smart Bookmarks from ground up, add a
  1262.         // separator below them in the bookmarks menu.
  1263.         if (smartBookmarksCurrentVersion == 0 &&
  1264.             smartBookmarkItemIds.length == 0) {
  1265.           let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.bookmarksMenuFolderId,
  1266.                                                         menuIndex);
  1267.           // Don't add a separator if the menu was empty or there is one already.
  1268.           if (id != -1 &&
  1269.               PlacesUtils.bookmarks.getItemType(id) != PlacesUtils.bookmarks.TYPE_SEPARATOR) {
  1270.             PlacesUtils.bookmarks.insertSeparator(PlacesUtils.bookmarksMenuFolderId,
  1271.                                                   menuIndex);
  1272.           }
  1273.         }
  1274.       }
  1275.     };
  1276.  
  1277.     try {
  1278.       PlacesUtils.bookmarks.runInBatchMode(batch, null);
  1279.     }
  1280.     catch(ex) {
  1281.       Components.utils.reportError(ex);
  1282.     }
  1283.     finally {
  1284.       Services.prefs.setIntPref(SMART_BOOKMARKS_PREF, SMART_BOOKMARKS_VERSION);
  1285.       Services.prefs.savePrefFile(null);
  1286.     }
  1287.   },
  1288.  
  1289. //@line 1431 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  1290.  
  1291.   // this returns the most recent non-popup browser window
  1292.   getMostRecentBrowserWindow: function BG_getMostRecentBrowserWindow() {
  1293.     function isFullBrowserWindow(win) {
  1294.       return !win.closed &&
  1295.              !win.document.documentElement.getAttribute("chromehidden");
  1296.     }
  1297.  
  1298. //@line 1440 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  1299.     var win = Services.wm.getMostRecentWindow("navigator:browser");
  1300.  
  1301.     // if we're lucky, this isn't a popup, and we can just return this
  1302.     if (win && !isFullBrowserWindow(win)) {
  1303.       win = null;
  1304.       let windowList = Services.wm.getEnumerator("navigator:browser");
  1305.       // this is oldest to newest, so this gets a bit ugly
  1306.       while (windowList.hasMoreElements()) {
  1307.         let nextWin = windowList.getNext();
  1308.         if (isFullBrowserWindow(nextWin))
  1309.           win = nextWin;
  1310.       }
  1311.     }
  1312.     return win;
  1313. //@line 1463 "/tmp/buildd/iceweasel-10.0.12esr/browser/components/nsBrowserGlue.js"
  1314.   },
  1315.  
  1316.  
  1317.   // for XPCOM
  1318.   classID:          Components.ID("{eab9012e-5f74-4cbc-b2b5-a590235513cc}"),
  1319.  
  1320.   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
  1321.                                          Ci.nsISupportsWeakReference,
  1322.                                          Ci.nsIBrowserGlue]),
  1323.  
  1324.   // redefine the default factory for XPCOMUtils
  1325.   _xpcom_factory: BrowserGlueServiceFactory,
  1326. }
  1327.  
  1328. function ContentPermissionPrompt() {}
  1329.  
  1330. ContentPermissionPrompt.prototype = {
  1331.   classID:          Components.ID("{d8903bf6-68d5-4e97-bcd1-e4d3012f721a}"),
  1332.  
  1333.   QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]),
  1334.  
  1335.   prompt: function CPP_prompt(request) {
  1336.  
  1337.     if (request.type != "geolocation") {
  1338.         return;
  1339.     }
  1340.  
  1341.     var requestingURI = request.uri;
  1342.  
  1343.     // Ignore requests from non-nsIStandardURLs
  1344.     if (!(requestingURI instanceof Ci.nsIStandardURL))
  1345.       return;
  1346.  
  1347.     var result = Services.perms.testExactPermission(requestingURI, "geo");
  1348.  
  1349.     if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
  1350.       request.allow();
  1351.       return;
  1352.     }
  1353.  
  1354.     if (result == Ci.nsIPermissionManager.DENY_ACTION) {
  1355.       request.cancel();
  1356.       return;
  1357.     }
  1358.  
  1359.     function getChromeWindow(aWindow) {
  1360.       var chromeWin = aWindow 
  1361.         .QueryInterface(Ci.nsIInterfaceRequestor)
  1362.         .getInterface(Ci.nsIWebNavigation)
  1363.         .QueryInterface(Ci.nsIDocShellTreeItem)
  1364.         .rootTreeItem
  1365.         .QueryInterface(Ci.nsIInterfaceRequestor)
  1366.         .getInterface(Ci.nsIDOMWindow)
  1367.         .QueryInterface(Ci.nsIDOMChromeWindow);
  1368.       return chromeWin;
  1369.     }
  1370.  
  1371.     var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
  1372.  
  1373.     var mainAction = {
  1374.       label: browserBundle.GetStringFromName("geolocation.shareLocation"),
  1375.       accessKey: browserBundle.GetStringFromName("geolocation.shareLocation.accesskey"),
  1376.       callback: function(notification) {
  1377.         request.allow();
  1378.       },
  1379.     };
  1380.  
  1381.     var message;
  1382.     var secondaryActions = [];
  1383.  
  1384.     // Different message/options if it is a local file
  1385.     if (requestingURI.schemeIs("file")) {
  1386.       message = browserBundle.formatStringFromName("geolocation.fileWantsToKnow",
  1387.                                                    [requestingURI.path], 1);
  1388.     } else {
  1389.       message = browserBundle.formatStringFromName("geolocation.siteWantsToKnow",
  1390.                                                    [requestingURI.host], 1);
  1391.  
  1392.       // Don't offer to "always/never share" in PB mode
  1393.       var inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
  1394.                               getService(Ci.nsIPrivateBrowsingService).
  1395.                               privateBrowsingEnabled;
  1396.  
  1397.       if (!inPrivateBrowsing) {
  1398.         secondaryActions.push({
  1399.           label: browserBundle.GetStringFromName("geolocation.alwaysShare"),
  1400.           accessKey: browserBundle.GetStringFromName("geolocation.alwaysShare.accesskey"),
  1401.           callback: function () {
  1402.             Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
  1403.             request.allow();
  1404.           }
  1405.         });
  1406.         secondaryActions.push({
  1407.           label: browserBundle.GetStringFromName("geolocation.neverShare"),
  1408.           accessKey: browserBundle.GetStringFromName("geolocation.neverShare.accesskey"),
  1409.           callback: function () {
  1410.             Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.DENY_ACTION);
  1411.             request.cancel();
  1412.           }
  1413.         });
  1414.       }
  1415.     }
  1416.  
  1417.     var requestingWindow = request.window.top;
  1418.     var chromeWin = getChromeWindow(requestingWindow).wrappedJSObject;
  1419.     var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document);
  1420.  
  1421.     chromeWin.PopupNotifications.show(browser, "geolocation", message, "geo-notification-icon",
  1422.                                       mainAction, secondaryActions);
  1423.   }
  1424. };
  1425.  
  1426. var components = [BrowserGlue, ContentPermissionPrompt];
  1427. var NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
  1428.